home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 8
/
Night Owl CD-ROM (NOPV8) (Night Owl Publisher) (1993).ISO
/
047a
/
lex_yacc.arj
/
PASLEX.L
< prev
next >
Wrap
Text File
|
1990-01-14
|
5KB
|
173 lines
%{
(*
* scan.l
*
* lex input file for pascal scanner
*
* extensions: to ways to spell "external" and "->" ok for "^".
*
* - PasLex.l: adapted to Turbo Pascal Lex 2-28-89 AG
* Note: keywords are determined by scanning a keyword table, rather
* than including the keyword patterns in the Lex source which is done
* in the original version of this file. The main reason for this is,
* that the DFA table generated from the original spec grows too large
* to be compilable by Turbo Pascal (Lex will construct the table,
* but Turbo Pascal puts it into the static data segment which holds
* all typed constants and global variables, and this data segment is
* 64 KB max.).
*)
unit PasLex;
interface
uses LexLib, YaccLib;
{$I Pas.h}
var
infile : string;
line_no : integer;
function yylex : integer;
function act_token : string;
implementation
const newline = #10;
procedure commenteof;
begin
writeln('unexpected EOF inside comment at line ', line_no);
end(*commenteof*);
function is_keyword(id : string; var token : integer) : boolean;
(* checks whether id is Pascal keyword; if so, returns corresponding
token number in token *)
forward;
%}
NQUOTE [^']
%%
var
c : char;
kw : integer;
[a-zA-Z]([a-zA-Z0-9])* if is_keyword(yytext, kw) then
return(kw)
else
return(IDENTIFIER);
":=" return(ASSIGNMENT);
'({NQUOTE}|'')+' return(CHARACTER_STRING);
":" return(COLON);
"," return(COMMA);
[0-9]+ return(DIGSEQ);
"." return(DOT);
".." return(DOTDOT);
"=" return(EQUAL);
">=" return(GE);
">" return(GT);
"[" return(LBRAC);
"<=" return(LE);
"(" return(LPAREN);
"<" return(LT);
"-" return(MINUS);
"<>" return(NOTEQUAL);
"+" return(PLUS);
"]" return(RBRAC);
[0-9]+"."[0-9]+ return(REALNUMBER);
")" return(RPAREN);
";" return(SEMICOLON);
"/" return(SLASH);
"*" return(STAR);
"**" return(STARSTAR);
"->" |
"^" return(UPARROW);
"(*" |
"{" begin
repeat
c := input;
case c of
'}' : exit;
'*' : begin
c := input;
if c=')' then exit else unput(c)
end;
newline : inc(line_no);
#0 : commenteof;
end;
until false
end;
[ \t\f] ;
\n inc(line_no);
. writeln('''', yytext[1], ''' (#', ord(yytext[1]),
'): illegal character at line ', line_no);
%%
function upper(id : string) : string;
var i : integer;
begin
for i := 1 to length(id) do
id[i] := upCase(id[i]);
upper := id
end(*upper*);
function is_keyword(id : string; var token : integer) : boolean;
const
id_len = 20;
type
Ident = string[id_len];
const
(* table of Pascal keywords: *)
no_of_keywords = 39;
keyword : array [1..no_of_keywords] of Ident = (
'AND', 'ARRAY', 'BEGIN', 'CASE',
'CONST', 'DIV', 'DO', 'DOWNTO',
'ELSE', 'END', 'EXTERNAL', 'EXTERN',
'FILE', 'FOR', 'FORWARD', 'FUNCTION',
'GOTO', 'IF', 'IN', 'LABEL',
'MOD', 'NIL', 'NOT', 'OF',
'OR', 'OTHERWISE', 'PACKED', 'PROCEDURE',
'PROGRAM', 'RECORD', 'REPEAT', 'SET',
'THEN', 'TO', 'TYPE', 'UNTIL',
'VAR', 'WHILE', 'WITH');
keyword_token : array [1..no_of_keywords] of integer = (
_AND, _ARRAY, _BEGIN, _CASE,
_CONST, _DIV, _DO, _DOWNTO,
_ELSE, _END, _EXTERNAL, _EXTERNAL,
(* EXTERNAL: 2 spellings (see above)! *)
_FILE, _FOR, _FORWARD, _FUNCTION,
_GOTO, _IF, _IN, _LABEL,
_MOD, _NIL, _NOT, _OF,
_OR, _OTHERWISE, _PACKED, _PROCEDURE,
_PROGRAM, _RECORD, _REPEAT, _SET,
_THEN, _TO, _TYPE, _UNTIL,
_VAR, _WHILE, _WITH);
var m, n, k : integer;
begin
id := upper(id);
m := 1; n := no_of_keywords;
while m<=n do
begin
k := m+(n-m) div 2;
if id=keyword[k] then
begin
is_keyword := true;
token := keyword_token[k];
exit
end
else if id>keyword[k] then
m := k+1
else
n := k-1
end;
is_keyword := false
end(*is_keyword*);
function act_token : string;
begin
act_token := yytext
end(*act_token*);
begin
write('input file: ');
readln(infile);
line_no := 1;
assign(yyin, infile);
reset(yyin);
end.